package com.jxbeidou.system.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jxbeidou.core.entity.SecurityUserVO;
import com.jxbeidou.system.api.user.dto.UserDTO;
import com.jxbeidou.system.menu.service.PermissionService;
import com.jxbeidou.system.menu.service.RoleService;
import com.jxbeidou.system.user.service.UserRoleService;
import lombok.AllArgsConstructor;
import com.jxbeidou.core.entity.PageResult;
import com.jxbeidou.core.mybatis.service.impl.BaseServiceImpl;
import com.jxbeidou.core.mybatis.convert.PageResultConvert;
import com.jxbeidou.system.user.convert.UserConvert;
import com.jxbeidou.system.user.entity.UserDO;
import com.jxbeidou.system.user.query.UserQuery;
import com.jxbeidou.system.user.vo.UserVO;
import com.jxbeidou.system.user.mapper.UserMapper;
import com.jxbeidou.system.user.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.List;

/**
 * 登录用户表
 *
 * @author 杜晓祥 
 * @since 1.0.0 2023-12-14
 */
@Service
@AllArgsConstructor
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO> implements UserService {

    @Resource
    private UserRoleService userRoleService;

    @Override
    public PageResult<UserVO> page(UserQuery query) {
        IPage<UserDO> page = baseMapper.selectPage(getPage(query), getWrapper(query));
        PageResult<UserVO> result = PageResultConvert.convert(page, entityList -> UserConvert.INSTANCE.convertList(entityList));
        return result;
    }

    @Override
    public SecurityUserVO loadUsername(String username) {
        LambdaQueryWrapper<UserDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StringUtils.isNotEmpty(username), UserDO::getUsername, username);
        UserDO userDO = baseMapper.selectOne(wrapper);
        if (userDO == null) {
            return null;
        }
        SecurityUserVO user = UserConvert.INSTANCE.convertSecurity(userDO);
        if (userDO.getSuperAdmin() == 1) {
            return user;
        }
        user.setRole(userRoleService.findByUserId(user.getId()));
        return user;
    }

    @Override
    public UserDTO selectUsername(String username) {
        LambdaQueryWrapper<UserDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StringUtils.isNotEmpty(username), UserDO::getUsername, username);
        UserDO userDO = baseMapper.selectOne(wrapper);
        if (userDO == null) {
            return null;
        }
        UserDTO user = UserConvert.INSTANCE.convertDto(userDO);
        if (userDO.getSuperAdmin() == 1) {
            return user;
        }
        user.setRole(userRoleService.findByUserId(user.getId()));
        return user;
    }

    private LambdaQueryWrapper<UserDO> getWrapper(UserQuery query){
        LambdaQueryWrapper<UserDO> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(query.getUsername()), UserDO::getUsername, query.getUsername());
        wrapper.eq(StringUtils.isNotEmpty(query.getRealName()), UserDO::getRealName, query.getRealName());
        wrapper.eq(StringUtils.isNotEmpty(query.getPhone()), UserDO::getPhone, query.getPhone());
        wrapper.eq(StringUtils.isNotEmpty(query.getEmail()), UserDO::getEmail, query.getEmail());
        wrapper.eq(query.getSex() != null, UserDO::getSex, query.getSex());
        wrapper.eq(query.getOrgId() != null, UserDO::getOrgId, query.getOrgId());
        wrapper.eq(query.getSuperAdmin() != null, UserDO::getSuperAdmin, query.getSuperAdmin());
        wrapper.eq(query.getStatus() != null, UserDO::getStatus, query.getStatus());
        return wrapper;
    }

    @Override
    public void save(UserVO vo) {
        UserDO entity = UserConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);
    }

    @Override
    public void update(UserVO vo) {
        UserDO entity = UserConvert.INSTANCE.convert(vo);

        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

}